package com.walkingfiles.registry

import org.springframework.dao.DataIntegrityViolationException

import grails.plugins.springsecurity.Secured

@Secured(['ROLE_USER'])
class TransferController {

	def springSecurityService
    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

    def index() {
        redirect(action: "list", params: params)
    }

    def list() {
	if (!params.sort) {
		params.sort = 'modifiedDate'
		params.order = 'desc'
	}

        params.max = Math.min(params.max ? params.int('max') : 10, 100)
        [transferInstanceList: Transfer.list(params), transferInstanceTotal: Transfer.count()]
    }

    def create() {
        [transferInstance: new Transfer(params)]
    }

    def save() {
	def transferInstance = new Transfer()
	transferInstance.subject = TransferSubject.get(params.subject.id)
	transferInstance.sourceArea = Area.get(session.currentAreaId)
	transferInstance.sendDate = new Date()
	transferInstance.sendUser = springSecurityService.currentUser
	transferInstance.destinationArea = Area.get(params.destinationArea.id)
	transferInstance.modifiedDate = transferInstance.sendDate

	if (params.sendComment?.comment?.trim())
		transferInstance.sendComment = new Comment(comment:params.sendComment.comment)

	transferInstance.transferDocuments = []

	List<Long> documentIds = null

	if (params.documentIds && params.documentIds instanceof String) {
		documentIds = new LinkedList<Long>()
		documentIds.add(params.documentIds as Long)
	}
	else {
		documentIds = params.documentIds as List<Long>
	}

	if (documentIds && documentIds.size > 0) {
		def documents = Document.getAll(documentIds)

		for (document in documents) {
			document.transfer = transferInstance
			document.modifiedDate = new Date()
			document.outbox = false
			def transferDocument = new TransferDocument(transfer: transferInstance, document:document, state:'N')
			transferInstance.transferDocuments += transferDocument
		}
	}

        if (!transferInstance.save(flush: true)) {
            render(view: "create", model: [transferInstance: transferInstance])
            return
        }

		def documents = Document.getAll(documentIds)
		for (document in documents) {
    		    LogItem.documentAttached(document, springSecurityService.currentUser.username, document.transfer)
		}

		flash.message = message(code: 'default.created.message', args: [message(code: 'transfer.label', default: 'Transfer'), transferInstance.id])
        redirect(action: "list")
    }

    def show() {
        def transferInstance = Transfer.get(params.id)
        if (!transferInstance) {
	    flash.message = message(code: 'default.not.found.message', args: [message(code: 'transfer.label', default: 'Transfer'), params.id])
            redirect(action: "list")
            return
        }

        [transferInstance: transferInstance]
    }

    def receive() {
        def transferInstance = Transfer.get(params.id)

        if (!transferInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'transfer.label', default: 'Transfer'), params.id])
            redirect(action: "list")
            return
        }

        [transferInstance: transferInstance]
    }

    def confirmReceive() {
        def transferInstance = Transfer.get(params.id)
        if (!transferInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'transfer.label', default: 'Transfer'), params.id])
            redirect(action: "list")
            return
        }

        if (params.version) {
            def version = params.version.toLong()
            if (transferInstance.version > version) {
                transferInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
                          [message(code: 'transfer.label', default: 'Transfer')] as Object[],
                          "Another user has updated this Transfer while you were editing")
                render(view: "receive", model: [transferInstance: transferInstance, receiveOption: params.transfer.receiveOption])
                return
            }
        }

	for (receiveOption in params.transfer.receiveOption) {
		if (!receiveOption.value) {
                transferInstance.errors.rejectValue("transferDocuments", "sarasa.sarasa",
                          [message(code: 'transfer.label', default: 'Transfer')] as Object[],
                          "Se requiere aceptar o rechazar cada transferencia.")

			render(view: "receive", model: [transferInstance: transferInstance, receiveOption: params.transfer.receiveOption])
			return
		}
	}

	transferInstance.receptionDate = new Date()
	transferInstance.receptionUser = springSecurityService.currentUser
	transferInstance.modifiedDate = transferInstance.receptionDate
	def currentArea = Area.get(session.currentAreaId)

	if (params.receptionComment?.comment?.trim())
		transferInstance.receptionComment = new Comment(comment:params.receptionComment.comment)

	for (transferDocument in transferInstance.transferDocuments) {
		transferDocument.state = params.transfer.receiveOption[transferDocument.id.toString()] == 'accept' ? 'A' : 'R'

		transferDocument.document.transfer = null
		transferDocument.document.modifiedDate = transferInstance.receptionDate
		transferDocument.document.outbox = false
		
		if (transferDocument.state == 'A') {
			transferDocument.document.currentArea = currentArea
			LogItem.transferAccepted(transferDocument.document, springSecurityService.currentUser.username, currentArea)
		} else {
			LogItem.transferRefused(transferDocument.document, springSecurityService.currentUser.username, currentArea)
		}
	}

        if (!transferInstance.save(flush: true)) {
            render(view: "edit", model: [transferInstance: transferInstance])
            return
        }

		flash.message = message(code: 'default.updated.message', args: [message(code: 'transfer.label', default: 'Transfer'), transferInstance.id])
        redirect(action: "show", id: transferInstance.id)
    }

    def delete() {
        def transferInstance = Transfer.get(params.id)
        if (!transferInstance) {
			flash.message = message(code: 'default.not.found.message', args: [message(code: 'transfer.label', default: 'Transfer'), params.id])
            redirect(action: "list")
            return
        }

        try {
            transferInstance.delete(flush: true)
			flash.message = message(code: 'default.deleted.message', args: [message(code: 'transfer.label', default: 'Transfer'), params.id])
            redirect(action: "list")
        }
        catch (DataIntegrityViolationException e) {
			flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'transfer.label', default: 'Transfer'), params.id])
            redirect(action: "show", id: params.id)
        }
    }
}

